﻿using BJ.AuthDomain.Commands;
using BJ.AuthDomain.IService;
using BJ.AuthEntity.Models;
using BJ.AuthEntity.ViewModels;
using Syspetro.Core.AppDeal;
using Syspetro.Core.CommandBus;
using Syspetro.Deploy.Managers;
using System.Threading.Tasks;

namespace BJ.AuthDomain.Service
{
    public class VerifyService : IVerifyService
    {
        readonly IAuthorizationManager _authorization;
        readonly IFreeSql _freeSql;
        readonly ICommandBus _command;
        public VerifyService(IFreeSql freeSql, IAuthorizationManager authorization, ICommandBus command)
        {
            _authorization = authorization;
            _freeSql = freeSql;
            _command = command;
        }

        public async Task<SpActionResult<bool>> BindEmail(string email, string code)
        {
            var rr = await VerifyEmail(email, code);
            if (rr.Success)
            {
                var uid = _authorization.GetUserId;
                bool bl = false;
                if (_authorization.IsAdmin)
                {
                    bl = await _freeSql.Update<AdminUser>(uid).Set(t => t.Emil, email).ExecuteAffrowsAsync() > 0;
                }
                else
                {
                    bl = await _freeSql.Update<User>(uid).Set(t => t.Emil, email).ExecuteAffrowsAsync() > 0;
                }
                if (bl)
                {
                    return new SpActionResult<bool>(true);
                }
                else
                {
                    return new SpActionResult<bool> { Success = false };
                }
            }
            return rr;
        }

        public async Task<SpActionResult<bool>> BindSMS(string phone, string code)
        {
            if (_authorization.GetPhone == phone)
                return new SpActionResult<bool> { Success = false, Msg = "不能与原手机号重复" };
            var rr = await VerifySMS(phone, code);
            if (rr.Success)
            {
                var uid = _authorization.GetUserId;
                bool bl = false;
                if (_authorization.IsAdmin)
                {
                    bl = await _freeSql.Update<AdminUser>(uid).Set(t => t.Phone, phone).ExecuteAffrowsAsync() > 0;
                }
                else
                {
                    bl = await _freeSql.Update<User>(uid).Set(t => t.Phone, phone).ExecuteAffrowsAsync() > 0;
                }
                if(bl)
                {
                    return new SpActionResult<bool>(true);
                }
                else
                {
                    return new SpActionResult<bool> { Success = false };
                }
            }
            return rr;
        }

        public SpActionResult<bool> Code_Email(VM_Code_Email code)
        {
            var ss = _command.Send(new SendEmailCommand { Email = code.Email });
            if (ss.Success)
                return new SpActionResult<bool>(true);
            else
                return new SpActionResult<bool> { Success = false, Msg = ss.Msg };
        }

        public async Task<SpActionResult<bool>> Code_Email()
        {
            return await Task.Run(() =>
            {
                var ss = _command.Send(new SendEmailCommandUser());
                if (ss.Success) return new SpActionResult<bool>(true);
                else return new SpActionResult<bool> { Success = false, Msg = ss.Msg };
            });
        }

        public SpActionResult<bool> Code_SMS(VM_Code_SMS code)
        {
            var ss = _command.Send(new SendSMSCommand { Phone = code.Phone });
            if (ss.Success) return new SpActionResult<bool>(true);
            else return new SpActionResult<bool> { Success = false, Msg = ss.Msg };
        }

        public async Task<SpActionResult<bool>> Code_SMS()
        {
            return await Task.Run(() =>
            {
                var ss = _command.Send(new SendSMSCommandUser());
                if (ss.Success) return new SpActionResult<bool>(true);
                else return new SpActionResult<bool> { Success = false, Msg = ss.Msg };
            });
        }

        public async Task<bool> IsSetEmail()
        {
            var uid = _authorization.GetUserId;
            if (_authorization.IsAdmin)
            {
                return await _freeSql.Select<AdminUser>().Where(t => t.Id == uid).Where(t => t.Emil != string.Empty).AnyAsync();
            }
            else
            {
                return await _freeSql.Select<User>().Where(t => t.Id == uid).Where(t => t.Emil != string.Empty).AnyAsync();
            }
        }

        public async Task<bool> IsSetGoogle()
        {
            var uid = _authorization.GetUserId;
            if (_authorization.IsAdmin)
            {
                return await _freeSql.Select<AdminUser>().Where(t => t.Id == uid).Where(t => t.Enable2FA != string.Empty).AnyAsync();
            }
            else
            {
                return await _freeSql.Select<User>().Where(t => t.Id == uid).Where(t => t.Enable2FA != string.Empty).AnyAsync();
            }
        }

        public async Task<bool> IsSetSMS()
        {
            var uid = _authorization.GetUserId;
            if (_authorization.IsAdmin)
            {
                return await _freeSql.Select<AdminUser>().Where(t => t.Id == uid).Where(t => t.Phone != string.Empty).AnyAsync();
            }
            else
            {
                return await _freeSql.Select<User>().Where(t => t.Id == uid).Where(t => t.Phone != string.Empty).AnyAsync();
            }
        }

        public async Task<SpActionResult<bool>> VerifyEmail(string email, string code)
        {
            return await Task.Run(() =>
            {
                var verf = _command.Send(new EmailVerifyCommand { Email = email, Captcha = code });
                if (verf.Success)
                {
                    return new SpActionResult<bool>(true);
                }
                else
                {
                    return new SpActionResult<bool> { Success = false, Msg = verf.Msg };
                }
            });
        }

        public async Task<SpActionResult<bool>> VerifySMS(string phone, string code)
        {
            return await Task.Run(() =>
            {
                var verf = _command.Send(new SMSVerifyCommand { Phone = phone, Captcha = code });
                if (verf.Success)
                {
                    return new SpActionResult<bool>(true);
                }
                else
                {
                    return new SpActionResult<bool> { Success = false, Msg = verf.Msg };
                }
            });
        }
    }
}
